package cn.alcatraz.pet.service.impl;

import cn.alcatraz.basic.exception.BusinessException;
import cn.alcatraz.basic.utils.BaiduAuditUtils;
import cn.alcatraz.basic.utils.CodeGenerateUtils;
import cn.alcatraz.basic.utils.DistanceUtil;
import cn.alcatraz.basic.utils.Point;
import cn.alcatraz.order.domain.OrderPetAcquisition;
import cn.alcatraz.order.mapper.OrderPetAcquisitionMapper;
import cn.alcatraz.org.domain.Shop;
import cn.alcatraz.org.mapper.ShopMapper;
import cn.alcatraz.pet.domain.Pet;
import cn.alcatraz.pet.domain.SearchMasterMsg;
import cn.alcatraz.pet.domain.SearchMasterMsgAuditLog;
import cn.alcatraz.pet.dto.HandlerMsgDto;
import cn.alcatraz.pet.mapper.PetMapper;
import cn.alcatraz.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.alcatraz.pet.mapper.SearchMasterMsgMapper;
import cn.alcatraz.pet.service.ISearchMasterMsgService;
import cn.alcatraz.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author alcatraz
 * @since 2022-07-19
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {


    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;

    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private OrderPetAcquisitionMapper orderPetAcquisitionMapper;

    @Autowired
    private PetMapper petMapper;

    @Override
    public void publish(SearchMasterMsg searchMasterMsg) {
        searchMasterMsgMapper.save(searchMasterMsg);
        // 1.非空校验，自己做，添加审核日志，提示用户必填字段没有填写数据

        StringBuffer sbf = new StringBuffer();
        sbf.append(searchMasterMsg.getName())
                .append(searchMasterMsg.getCoatColor())
                .append(searchMasterMsg.getTitle())
                .append(searchMasterMsg.getAddress());
        if (!BaiduAuditUtils.TextCensor(sbf.toString())){
            //审核失败设置寻主状态为待审核并保存审核日志
            searchMasterMsg.setState(0);
            SearchMasterMsgAuditLog msg = new SearchMasterMsgAuditLog();
            msg.setMsgId(searchMasterMsg.getId());
            msg.setAuditTime(new Date());
            msg.setNote("文字审核失败，可能失败的原因：宠物毛色、寻主标题、地址、宠物名称");
            searchMasterMsgAuditLogMapper.save(msg);
        }else {
            //审核通过那判断距离方圆50公里是否有店铺存在
            List<Shop> shops = shopMapper.loadAll();
            //得到用户地址
            Point point = DistanceUtil.getPoint(searchMasterMsg.getAddress());
            //调用工具类计算得到50公里内店铺
            Shop shop = DistanceUtil.getNearestShop(point, shops);
            //找到店铺给当前寻主消息绑定店铺
            if (shop != null){
                // 把当前寻主消息绑定给店铺
                searchMasterMsg.setShopId(shop.getId());
            }
        }
        searchMasterMsgMapper.update(searchMasterMsg);
    }

    @Override
    public void accept(HandlerMsgDto handlerMsgDto) {
        // 校验参数是否为空，自己做
        // 1.确定是否已经被接单，万一有两个人同时点击接单，怎么办？以后我们用加锁处理，现在我们先查询一下
        /*
            情况分析：state != -1 searcherMasterMsgId = handlerMsgDto.msgId
                1.当前寻主消息是第一次被接单，那么没有在收购订单中应该查询不到
                2.当前寻主消息不是第一次被接单了，那么说明之前生成过
                3.如何判定是否可以接单：
                    1.如果查询不到收购单那么就可以接单
                    2.即便查询的到收购单，但是收购单的消息需要为-1，只要不是-1，并且查询到了，都不能接单
        */
        OrderPetAcquisition orderPetAcquisition = orderPetAcquisitionMapper.loadByOrderReceived(handlerMsgDto.getMsgId());
        if (orderPetAcquisition != null){
            throw new BusinessException("该订单被抢了！");
        }
        // 1.查询寻主消息
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.loadById(handlerMsgDto.getMsgId());
        // 2.生成宠物信息，并保存
        Pet pet = msg2Pet(searchMasterMsg);
        petMapper.save(pet); // 需要返回主键
        // 3.初始化订单对象并保存
        orderPetAcquisition = initOrderPetAcquisition(handlerMsgDto, searchMasterMsg, pet);
        orderPetAcquisitionMapper.save(orderPetAcquisition);

    }

    // 拒单
    @Override
    public void reject(Long msgId) {
        // 1.参数校验
        // 2.根据消息Id查询寻主消息，将shopId置空，并修改
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.loadById(msgId);
        if (searchMasterMsg == null){
            throw new BusinessException("此订单不存在！");
        }
        searchMasterMsg.setShopId(null);
        searchMasterMsgMapper.update(searchMasterMsg);
        // 3.记录日志，自行完成，自己判断那张表是拒单日志表，如果没有自己创建
    }

    // ctrl + alt + m 快速抽取代码为方法
    private OrderPetAcquisition initOrderPetAcquisition(HandlerMsgDto handlerMsgDto, SearchMasterMsg searchMasterMsg, Pet pet) {
        // 3.生成收购单，本来也应该抽取一个方法，但是等会儿要教你们一个操作，所以等会儿再抽
        OrderPetAcquisition orderPetAcquisition = new OrderPetAcquisition();
        // 使用工具类生成订单编号
        String orderSn = CodeGenerateUtils.generateOrderSn(searchMasterMsg.getUserId());
        orderPetAcquisition.setOrderSn(orderSn);
        orderPetAcquisition.setDigest(handlerMsgDto.getNote());
        // 最迟的处理订单的时间
        orderPetAcquisition.setLastcomfirmtime(new Date(System.currentTimeMillis() + 2*24*60*60*1000));
        // 这时候还不是最终价格，因为我们销售人员可以去讲价，加价之后的才是最终价格
        orderPetAcquisition.setPrice(searchMasterMsg.getPrice());
        orderPetAcquisition.setPetId(pet.getId());
        orderPetAcquisition.setUserId(searchMasterMsg.getUserId());
        orderPetAcquisition.setShopId(searchMasterMsg.getShopId());
        orderPetAcquisition.setAddress(searchMasterMsg.getAddress());
        orderPetAcquisition.setEmpId(handlerMsgDto.getHandler());
        orderPetAcquisition.setSearchMasterMsgId(searchMasterMsg.getId());
        return orderPetAcquisition;
    }


    private Pet msg2Pet(SearchMasterMsg searchMasterMsg) {
        // 2.根据寻主消息初始化宠物信息
        Pet pet = new Pet();
        pet.setName(searchMasterMsg.getName());
        pet.setCostprice(searchMasterMsg.getPrice());
        pet.setTypeId(searchMasterMsg.getPetType());
        pet.setShopId(searchMasterMsg.getShopId());
        pet.setSearchMasterMsgId(searchMasterMsg.getId());
        return pet;
    }

}
